; #INDEX# ======================================================================================================================= ; Title .........: IStream UDF ; AutoIt Version : 3.3.16.1 ; Language ......: English ; Description ...: User Defined Function (UDF) for creating and interacting with IStream COM objects, implementing all IStream ; interface methods for stream operations such as reading, writing, seeking, and copying. ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Utilizes native AutoIt COM functionality without dependencies on AutoItObject.au3. Includes robust error ; handling for COM operations. Related to StructuredStorage.au3 for advanced storage operations. ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nn-objidl-istream ; ; Index: ; Constants: ; - Interface IDs ($IID_IStream, $IID_IStorage, $IID_IEnumSTATSTG, $IID_IPropertySetStorage) ; - STGM Flags ($STGM_READ, $STGM_WRITE, $STGM_READWRITE, etc.) ; - STGFMT Constants ($STGFMT_STORAGE, $STGFMT_FILE, etc.) ; - STGOPTIONS Constants and Structure ($STGOPTIONS_VERSION_0, $tagSTGOPTIONS, etc.) ; - STGC Commit Flags ($STGC_DEFAULT, $STGC_OVERWRITE, etc.) ; - STGMOVE Flags ($STGMOVE_MOVE, $STGMOVE_COPY, etc.) ; - Seek Origins ($STREAM_SEEK_SET, $STREAM_SEEK_CUR, $STREAM_SEEK_END) ; - Lock Types ($LOCK_WRITE, $LOCK_EXCLUSIVE, $LOCK_ONLYONCE) ; - STATSTG Structure and Flags ($tagSTATSTG, $STATFLAG_DEFAULT, etc.) ; - COM Interface Definitions ($sIID_ISequentialStream, $tagIStream, etc.) ; - HRESULT Error Codes ($tagStreamStorageErrorTable) ; #CURRENT# ===================================================================================================================== ;_IsObjType ;_IsStream ;_IStream_GetErrorInfo ;_SHCreateStreamOnFileEx ;_StreamCreateMemoryBuffer ;_SHCreateMemStream ;_StreamCreateFromData ;_StreamCreateFromDataOnHGlobal ;_CreateStreamFromPtr ;_StreamRelease ;_StreamRead ;_StreamWrite ;_StreamSeek ;_StreamSetSize ;_StreamGetStat ;_StreamGetType ;_StreamGetName ;_StreamGetSize ;_StreamCopyTo ;_StreamCopyToEx ;_StreamClone ;_StreamLockRegion ;_StreamUnlockRegion ;_StreamCommit ;_StreamRevert ;_StreamQueryInterface ;_WinAPI_GetBufferData ; =============================================================================================================================== ; #INTERNAL_NO_DOC# ============================================================================================================= ;__COM_IUnknownAddRef ;__COM_IUnknownAddRefPtr ;__ReadStreamName ;__IStreamErrorInfo ;_StatDisplay ; =============================================================================================================================== #include-once #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 #include #include #include ; #CONSTANTS# =================================================================================================================== ; Interface IDs Global Const $IID_IStream = "{0000000C-0000-0000-C000-000000000046}" Global Const $IID_IStorage = "{0000000B-0000-0000-C000-000000000046}" Global Const $IID_IEnumSTATSTG = "{0000000D-0000-0000-C000-000000000046}" Global Const $IID_IPropertySetStorage = "{0000013A-0000-0000-C000-000000000046}" ; STGM Flags Global Const $STGM_READ = 0x00000000 Global Const $STGM_WRITE = 0x00000001 Global Const $STGM_READWRITE = 0x00000002 Global Const $STGM_SHARE_EXCLUSIVE = 0x00000010 Global Const $STGM_SHARE_DENY_READ = 0x00000030 Global Const $STGM_SHARE_DENY_WRITE = 0x00000020 Global Const $STGM_SHARE_DENY_NONE = 0x00000040 Global Const $STGM_CREATE = 0x00001000 Global Const $STGM_CONVERT = 0x00020000 Global Const $STGM_FAILIFTHERE = 0x00000000 Global Const $STGM_DIRECT = 0x00000000 Global Const $STGM_TRANSACTED = 0x00010000 Global Const $STGM_NOSCRATCH = 0x00100000 Global Const $STGM_NOSNAPSHOT = 0x00200000 Global Const $STGM_SIMPLE = 0x08000000 Global Const $STGM_DIRECT_SWMR = 0x00400000 Global Const $STGM_DELETEONRELEASE = 0x04000000 Global Const $STGM_PRIORITY = 0x00040000 ; STGFMT Constants Global Const $STGFMT_STORAGE = 0 Global Const $STGFMT_FILE = 3 Global Const $STGFMT_ANY = 4 Global Const $STGFMT_DOCFILE = 5 ; STGOPTIONS Constants and Structure Global Const $STGOPTIONS_VERSION_0 = 0 Global Const $STGOPTIONS_VERSION_1 = 1 Global Const $STGOPTIONS_VERSION_2 = 2 Global Const $tagSTGOPTIONS = "ushort usVersion; ushort reserved; ulong ulSectorSize; ptr pwcsTemplateFile" ; STGC Commit Flags Global Const $STGC_DEFAULT = 0 Global Const $STGC_OVERWRITE = 1 Global Const $STGC_ONLYIFCURRENT = 2 Global Const $STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE = 4 Global Const $STGC_CONSOLIDATE = 8 ; STGMOVE Flags Global Enum $STGMOVE_MOVE = 0, $STGMOVE_COPY = 1, $STGMOVE_SHALLOWCOPY = 2 ; Seek Origins Global Const $STREAM_SEEK_SET = 0 Global Const $STREAM_SEEK_CUR = 1 Global Const $STREAM_SEEK_END = 2 ; Lock Types Global Const $LOCK_WRITE = 1 Global Const $LOCK_EXCLUSIVE = 2 Global Const $LOCK_ONLYONCE = 4 ; STATSTG Structure and Flags Global Const $tagSTATSTG = _ "struct;" & _ "ptr pwcsName;" & _ "dword type;" & _ "uint64 cbSize;" & _ "dword mtime_low;dword mtime_high;" & _ "dword ctime_low;dword ctime_high;" & _ "dword atime_low;dword atime_high;" & _ "dword grfMode;" & _ "dword grfLocksSupported;" & _ "byte clsid[16];" & _ "dword grfStateBits;" & _ "dword reserved;" & _ "endstruct" Global Enum $STATFLAG_DEFAULT = 0, $STATFLAG_NONAME = 1, $STATFLAG_NOOPEN = 2 Global Enum $STGTY_STORAGE = 1, $STGTY_STREAM = 2, $STGTY_LOCKBYTES = 3, $STGTY_PROPERTY = 4 ; COM Interface Definitions #interface "ISequentialStream" Global Const $sIID_ISequentialStream = "{0C733A30-2A1C-11CE-ADE5-00AA0044773D}" Global $dtagISequentialStream = _ "Read hresult(ptr;dword;dword*);" & _ "Write hresult(ptr;dword;dword*);" #interface "IStream" Global Const $sIID_IStream = "{0000000C-0000-0000-C000-000000000046}" Global $tagIStream = $dtagISequentialStream & _ "Seek hresult(int64;dword;uint64*);" & _ "SetSize hresult(int64);" & _ "CopyTo hresult(ptr;int64;uint64*;uint64*);" & _ "Commit hresult(dword);" & _ "Revert hresult();" & _ "LockRegion hresult(int64;int64;dword);" & _ "UnlockRegion hresult(int64;int64;dword);" & _ "Stat hresult(ptr;dword);" & _ "Clone hresult(ptr*);" ; HRESULT Error Codes Global Const $tagStreamStorageErrorTable = [ _ ["0x80030001", "STG_E_INVALIDFUNCTION", "Invalid function for object type.", "IStream: Revert, Commit, LockRegion, UnlockRegion"], _ ["0x80030002", "STG_E_FILENOTFOUND", "File or stream does not exist.", "IStream: Stat"], _ ["0x80030003", "STG_E_PATHNOTFOUND", "Invalid or non-existent path.", "SHCreateStreamOnFileEx"], _ ["0x80030004", "STG_E_TOOMANYOPENFILES", "Too many open files or streams.", "IStream: Create, Open"], _ ["0x80030005", "STG_E_ACCESSDENIED", "Access denied due to permissions.", "IStream: Create, Open, Read, Write"], _ ["0x80030006", "STG_E_INSUFFICIENTMEMORY", "Insufficient memory.", "IStream: Read, Write, SetSize, CopyTo, Clone"], _ ["0x80030008", "STG_E_INVALIDSTORAGE", "Invalid or corrupted storage.", "SHCreateStreamOnFileEx"], _ ["0x8003001D", "STG_E_INVALIDPOINTER", "Invalid pointer.", "IStream: Read, Write, Seek, SetSize, CopyTo, Stat, Clone"], _ ["0x80030020", "STG_E_LOCKVIOLATION", "Access violation due to locked region.", "IStream: Read, Write, LockRegion, UnlockRegion"], _ ["0x80030021", "STG_E_FILEALREADYEXISTS", "Stream or file already exists.", "IStream: Create"], _ ["0x80030050", "STG_E_INVALIDNAME", "Invalid stream name.", "IStream: Stat"], _ ["0x80030057", "STG_E_INVALIDPARAMETER", "Invalid parameter.", "IStream: Seek, CopyTo, Commit, LockRegion, UnlockRegion"], _ ["0x80030070", "STG_E_MEDIUMFULL", "Storage medium is full.", "IStream: Write, SetSize, CopyTo"], _ ["0x800300F0", "STG_E_READFAULT", "Error reading from stream.", "IStream: Read, CopyTo"], _ ["0x800300FA", "STG_E_WRITEFAULT", "Error writing to stream.", "IStream: Write, CopyTo, SetSize"], _ ["0x80030102", "STG_E_REVERTED", "Stream was reverted and is invalid.", "IStream: Read, Write, Seek"], _ ["0x80030103", "STG_E_NOTCURRENT", "Stream modified since last operation.", "IStream: Commit, Revert"], _ ["0x80030104", "STG_E_CANTSAVE", "Unable to save changes.", "IStream: Commit"], _ ["0x80030108", "STG_E_NOTINSTORAGE", "Element not in storage.", "IStorage: OpenStream"], _ ["0x80030109", "STG_E_INVALIDFLAG", "Invalid flag specified.", "IStream: Create, Open"], _ ["0x8007000E", "E_OUTOFMEMORY", "Insufficient memory.", "IStream: Read, Write, SetSize, CopyTo, Clone"], _ ["0x80070057", "E_INVALIDARG", "Invalid argument.", "IStream: All methods"], _ ["0x80004001", "E_NOTIMPL", "Method not implemented.", "IStream: LockRegion, UnlockRegion"], _ ["0x80004005", "E_FAIL", "Unspecified failure.", "IStream: All methods"] _ ] ; #FUNCTION# ==================================================================================================================== ; Name ..........: _IsObjType ; Description ...: Checks if a COM object supports a specified interface. ; Syntax ........: _IsObjType(ByRef $oObject, $sIID) ; Parameters ....: $oObject - COM object to test. ; $sIID - Interface Identifier (GUID) as a string. ; Return values .: Success - 1 if interface is supported. ; Failure - 0, sets @error: ; |1 - Invalid COM object. ; |2 - Invalid or empty IID string. ; |3 - Failed to convert IID to GUID. ; |4 - QueryInterface call failed. ; |5 - QueryInterface returned non-zero HRESULT. ; |6 - No interface pointer obtained. ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Releases interface pointer to prevent memory leaks. ; Related .......: _IsStream, _StreamQueryInterface ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-queryinterface ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _IsObjType(ByRef $oObject, $sIID) If Not IsObj($oObject) Then Return SetError(1, 0, 0) If Not IsString($sIID) Or $sIID = "" Then Return SetError(2, 0, 0) Local $tRIID = _WinAPI_GUIDFromString($sIID) If Not IsDllStruct($tRIID) Then Return SetError(3, 0, 0) Local $pInterface Local $iResult = $oObject.QueryInterface(DllStructGetPtr($tRIID), $pInterface) If @error Then Return SetError(4, $iResult, 0) If $iResult <> 0 Then Return SetError(5, $iResult, 0) If $pInterface Then DllCall("ole32.dll", "ulong", "Release", "ptr", $pInterface) Return 1 EndIf Return SetError(6, 0, 0) EndFunc ;==>_IsObjType ; #FUNCTION# ==================================================================================================================== ; Name ..........: _IsStream ; Description ...: Verifies if a COM object supports the IStream interface. ; Syntax ........: _IsStream(ByRef $oObject) ; Parameters ....: $oObject - COM object to test. ; Return values .: Success - 1 if IStream interface is supported. ; Failure - 0, sets @error (see _IsObjType). ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Uses $IID_IStream for verification. ; Related .......: _IsObjType, _SHCreateStreamOnFileEx ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nn-objidl-istream ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _IsStream(ByRef $oObject) Return _IsObjType($oObject, $IID_IStream) EndFunc ;==>_IsStream ; #FUNCTION# ==================================================================================================================== ; Name ..........: _IStream_GetErrorInfo ; Description ...: Retrieves error information for an HRESULT code. ; Syntax ........: _IStream_GetErrorInfo($iHRESULT) ; Parameters ....: $iHRESULT - HRESULT error code. ; Return values .: Success - Array: [Symbolic name, Description, Affected methods]. ; Failure - -1, sets @error to 1 (HRESULT not found). ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Uses $tagStreamStorageErrorTable for error lookup. ; Related .......: $tagStreamStorageErrorTable ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _IStream_GetErrorInfo($iHRESULT) Local $sHRESULT = StringLower(StringFormat("0x%08X", $iHRESULT)) For $i = 0 To UBound($tagStreamStorageErrorTable) - 1 If $tagStreamStorageErrorTable[$i][0] = $sHRESULT Then Local $aError = [$tagStreamStorageErrorTable[$i][1], $tagStreamStorageErrorTable[$i][2], $tagStreamStorageErrorTable[$i][3]] Return $aError EndIf Next Return SetError(1, 0, -1) EndFunc ;==>_IStream_GetErrorInfo ; #FUNCTION# ==================================================================================================================== ; Name ..........: _SHCreateStreamOnFileEx ; Description ...: Creates an IStream object from a file. ; Syntax ........: _SHCreateStreamOnFileEx($sFile[, $grfMode[, $dwAttributes[, $fCreate]]]) ; Parameters ....: $sFile - File path. ; $grfMode - [optional] STGM flags (default: $STGM_READWRITE | $STGM_SHARE_DENY_WRITE | $STGM_CREATE). ; $dwAttributes - [optional] File attributes (default: FILE_ATTRIBUTE_NORMAL). ; $fCreate - [optional] Create/overwrite file if True (default: True). ; Return values .: Success - IStream COM object. ; Failure - 0, sets @error: ; |1 - File does not exist and $fCreate is False. ; |2 - Invalid file path. ; |3 - DllCall failed (HRESULT in @extended). ; |4 - Failed to create COM object. ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Release returned object with _StreamRelease. ; Related .......: _StreamCreateFromDataOnHGlobal, _StreamRelease ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-shcreatestreamonfileex ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _SHCreateStreamOnFileEx($sFile, $grfMode = Default, $dwAttributes = Default, $fCreate = True) If Not IsString($sFile) Or $sFile = "" Then Return SetError(2, 0, 0) If Not $fCreate And Not FileExists($sFile) Then Return SetError(1, 0, 0) If $grfMode = Default Then $grfMode = BitOR($STGM_READWRITE, $STGM_SHARE_DENY_WRITE, $fCreate ? $STGM_CREATE : 0) If $dwAttributes = Default Then $dwAttributes = 0x80 ; FILE_ATTRIBUTE_NORMAL Local $iResult = DllCall("Shlwapi.dll", "long", "SHCreateStreamOnFileEx", _ "wstr", $sFile, "dword", $grfMode, "dword", $dwAttributes, "bool", $fCreate, "ptr", 0, "ptr*", 0) If @error Or $iResult[0] <> 0 Then Return SetError(3, $iResult[0], 0) Local $oStream = ObjCreateInterface($iResult[6], $sIID_IStream, $tagIStream) If Not IsObj($oStream) Then DllCall("ole32.dll", "ulong", "Release", "ptr", $iResult[6]) Return SetError(4, 0, 0) EndIf Return $oStream EndFunc ;==>_SHCreateStreamOnFileEx ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamCreateMemoryBuffer ; Description ...: Creates a memory buffer from binary or string data. ; Syntax ........: _StreamCreateMemoryBuffer($bData, ByRef $iSize) ; Parameters ....: $bData - Binary or string data. ; $iSize - [out] Size of allocated buffer in bytes. ; Return values .: Success - Pointer to memory buffer. ; Failure - 0, sets @error to 1 (allocation failed). ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Free returned pointer with _WinAPI_FreeMemory. ; Related .......: _StreamWrite, _WinAPI_GetBufferData ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalalloc ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamCreateMemoryBuffer($bData, ByRef $iSize) If Not IsBinary($bData) Then $bData = Binary($bData) Local $iBytes = BinaryLen($bData) Local $pMemory = _WinAPI_CreateBuffer($iBytes) If Not $pMemory Then Return SetError(1, 0, 0) Local $tData = DllStructCreate("byte[" & $iBytes & "]", $pMemory) DllStructSetData($tData, 1, $bData) $iSize = _WinAPI_GetMemorySize($pMemory) Return $pMemory EndFunc ;==>_StreamCreateMemoryBuffer ; #FUNCTION# ==================================================================================================================== ; Name ..........: _SHCreateMemStream ; Description ...: Creates an IStream object from a memory buffer. ; Syntax ........: _SHCreateMemStream($pBuffer, $cbInit) ; Parameters ....: $pBuffer - Pointer to memory buffer. ; $cbInit - Size of initial data in buffer. ; Return values .: Success - IStream COM object. ; Failure - 0, sets @error: ; |1 - Invalid buffer. ; |2 - DllCall failed. ; |3 - Failed to create COM object. ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Release returned object with _StreamRelease. ; Related .......: _StreamCreateFromData, _StreamRelease ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-shcreatememstream ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _SHCreateMemStream($pBuffer, $cbInit) If Not $pBuffer Then Return SetError(1, 0, 0) Local $iResult = DllCall("Shlwapi.dll", "ptr", "SHCreateMemStream", "ptr", $pBuffer, "uint", $cbInit) If @error Or Not $iResult[0] Then Return SetError(2, 0, 0) Local $oStream = ObjCreateInterface($iResult[0], $sIID_IStream, $tagIStream) If Not IsObj($oStream) Then DllCall("ole32.dll", "ulong", "Release", "ptr", $iResult[0]) Return SetError(3, 0, 0) EndIf Return $oStream EndFunc ;==>_SHCreateMemStream ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamCreateFromData ; Description ...: Creates an IStream object from binary or string data. ; Syntax ........: _StreamCreateFromData($vData, ByRef $iSize) ; Parameters ....: $vData - Binary or string data. ; $iSize - [out] Size of allocated buffer in bytes. ; Return values .: Success - IStream COM object. ; Failure - 0, sets @error: ; |1 - Memory allocation failed. ; |2 - Stream creation failed. ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Memory is freed internally. Release returned object with _StreamRelease. ; Related .......: _StreamCreateMemoryBuffer, _SHCreateMemStream ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/shlwapi/nf-shlwapi-shcreatememstream ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamCreateFromData($vData, ByRef $iSize) Local $pMemory = _StreamCreateMemoryBuffer($vData, $iSize) If @error Then Return SetError(1, 0, 0) Local $oStream = _SHCreateMemStream($pMemory, $iSize) If @error Then _WinAPI_FreeMemory($pMemory) $iSize = 0 Return SetError(2, @error, 0) EndIf _WinAPI_FreeMemory($pMemory) Return $oStream EndFunc ;==>_StreamCreateFromData ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamCreateFromDataOnHGlobal ; Description ...: Creates an IStream object using CreateStreamOnHGlobal. ; Syntax ........: _StreamCreateFromDataOnHGlobal($vData, ByRef $iSize[, $fDeleteOnRelease]) ; Parameters ....: $vData - Binary or string data. ; $iSize - [out] Size of allocated buffer in bytes. ; $fDeleteOnRelease - [optional] Free memory on release if True (default: True). ; Return values .: Success - IStream COM object. ; Failure - 0, sets @error: ; |1 - Memory allocation failed. ; |2 - Failed to create global memory handle. ; |3 - Failed to create stream. ; |4 - Failed to create COM object. ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Release returned object with _StreamRelease. If $fDeleteOnRelease is False, free HGLOBAL manually. ; Related .......: _StreamCreateMemoryBuffer, _StreamRelease ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/ole2/nf-ole2-createstreamonhglobal ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamCreateFromDataOnHGlobal($vData, ByRef $iSize, $fDeleteOnRelease = True) If Not IsBinary($vData) Then $vData = Binary($vData) Local $iBytes = BinaryLen($vData) Local $hGlobal = _MemGlobalAlloc($iBytes, $GMEM_MOVEABLE) If Not $hGlobal Then Return SetError(1, 0, 0) If $iBytes Then Local $pMemory = _MemGlobalLock($hGlobal) If Not $pMemory Then _MemGlobalFree($hGlobal) Return SetError(2, 0, 0) EndIf Local $tData = DllStructCreate("byte[" & $iBytes & "]", $pMemory) DllStructSetData($tData, 1, $vData) _MemGlobalUnlock($hGlobal) EndIf Local $pStream = _WinAPI_CreateStreamOnHGlobal($hGlobal, $fDeleteOnRelease) If Not $pStream Then _MemGlobalFree($hGlobal) Return SetError(3, @error, 0) EndIf Local $oStream = ObjCreateInterface($pStream, $sIID_IStream, $tagIStream) If Not IsObj($oStream) Then _WinAPI_ReleaseStream($pStream) _MemGlobalFree($hGlobal) Return SetError(4, 0, 0) EndIf $iSize = $iBytes Return $oStream EndFunc ;==>_StreamCreateFromDataOnHGlobal ; #FUNCTION# ==================================================================================================================== ; Name ..........: _CreateStreamFromPtr ; Description ...: Creates an IStream object from a raw IStream interface pointer. ; Syntax ........: _CreateStreamFromPtr($pStream) ; Parameters ....: $pStream - Pointer to IStream COM interface. ; Return values .: Success - IStream COM object. ; Failure - 0, sets @error: ; |1 - Invalid or null pointer. ; |2 - Failed to create COM object. ; |3 - Failed to add reference. ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Release returned object with _StreamRelease and pointer with DllCall("ole32.dll", "ulong", "Release", "ptr", ...). ; Related .......: _StreamCopyTo, _StreamQueryInterface ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nn-objidl-istream ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _CreateStreamFromPtr($pStream) If Not $pStream Then Return SetError(1, 0, 0) If Not __COM_IUnknownAddRefPtr($pStream) Then Return SetError(3, 0, 0) Local $oStream = ObjCreateInterface($pStream, $sIID_IStream, $tagIStream) If Not IsObj($oStream) Then Return SetError(2, 0, 0) Return $oStream EndFunc ;==>_CreateStreamFromPtr ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamRelease ; Description ...: Releases an IStream COM object. ; Syntax ........: _StreamRelease(ByRef $oStream) ; Parameters ....: $oStream - IStream COM object. ; Return values .: None ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Decrements reference count. Manually release additional pointers (e.g., from _StreamClone). ; Related .......: _StreamQueryInterface, _CreateStreamFromPtr ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-release ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamRelease(ByRef $oStream) $oStream = 0 EndFunc ;==>_StreamRelease ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamRead ; Description ...: Reads data from a stream. ; Syntax ........: _StreamRead(ByRef $oStream, $iSize, ByRef $pMemory, ByRef $iReadSize) ; Parameters ....: $oStream - IStream COM object. ; $iSize - Number of bytes to read. ; $pMemory - [out] Pointer to allocated read buffer. ; $iReadSize - [out] Number of bytes actually read. ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - Invalid stream object. ; |2 - Memory allocation failed. ; |3 - COM error (HRESULT in @extended). ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Free $pMemory with _WinAPI_FreeMemory. ; Related .......: _StreamWrite, _WinAPI_GetBufferData ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-istream-read ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamRead(ByRef $oStream, $iSize, ByRef $pMemory, ByRef $iReadSize) If Not IsObj($oStream) Then Return SetError(1, 0, 0) $pMemory = _WinAPI_CreateBuffer($iSize) If Not $pMemory Then Return SetError(2, 0, 0) Local $iRet = $oStream.Read($pMemory, $iSize, $iReadSize) If @error Then _WinAPI_FreeMemory($pMemory) $pMemory = 0 Return SetError(3, $iRet, 0) EndIf Return SetError(0, $iRet, $iRet = 0) EndFunc ;==>_StreamRead ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamWrite ; Description ...: Writes data to a stream. ; Syntax ........: _StreamWrite(ByRef $oStream, $pMemory, $iSize, ByRef $iWrittenSize[, $bCommit]) ; Parameters ....: $oStream - IStream COM object. ; $pMemory - Pointer to data buffer. ; $iSize - Size of data to write (bytes). ; $iWrittenSize - [out] Number of bytes written. ; $bCommit - [optional] Commit changes (default: True). ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - Invalid stream object. ; |2 - COM error (HRESULT in @extended). ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Free $pMemory with _WinAPI_FreeMemory. ; Related .......: _StreamRead, _StreamCreateMemoryBuffer ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-istream-write ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamWrite(ByRef $oStream, $pMemory, $iSize, ByRef $iWrittenSize, $bCommit = True) If Not IsObj($oStream) Then Return SetError(1, 0, 0) Local $iResult = $oStream.Write($pMemory, $iSize, $iWrittenSize) If @error Or $iResult <> 0 Then Return SetError(2, $iResult, 0) If $bCommit Then Local $iCommit = $oStream.Commit($STGC_DEFAULT) If @error Or $iCommit <> 0 Then Return SetError(2, $iCommit, 0) EndIf Return 1 EndFunc ;==>_StreamWrite ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamSeek ; Description ...: Moves the stream pointer to a specified position. ; Syntax ........: _StreamSeek(ByRef $oStream[, $iMove[, $dwOrigin]]) ; Parameters ....: $oStream - IStream COM object. ; $iMove - [optional] Bytes to move (default: 0). ; $dwOrigin - [optional] Starting point (default: $STREAM_SEEK_CUR). ; Return values .: Success - New stream pointer position. ; Failure - 0, sets @error: ; |1 - Invalid stream object. ; |2 - COM error (HRESULT in @extended). ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Uses $STREAM_SEEK_SET, $STREAM_SEEK_CUR, or $STREAM_SEEK_END. ; Related .......: _StreamRead, _StreamWrite ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-istream-seek ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamSeek(ByRef $oStream, $iMove = 0, $dwOrigin = $STREAM_SEEK_CUR) If Not IsObj($oStream) Then Return SetError(1, 0, 0) Local $iPosition = 0 Local $iResult = $oStream.Seek($iMove, $dwOrigin, $iPosition) If @error Or $iResult <> 0 Then Return SetError(2, $iResult, 0) Return $iPosition EndFunc ;==>_StreamSeek ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamSetSize ; Description ...: Changes the stream size. ; Syntax ........: _StreamSetSize(ByRef $oStream, $iNewSize) ; Parameters ....: $oStream - IStream COM object. ; $iNewSize - New stream size in bytes. ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - Invalid stream object. ; |2 - COM error (HRESULT in @extended). ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Truncates or extends stream; extended areas filled with zeros. ; Related .......: _StreamWrite, _StreamGetStat ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-istream-setsize ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamSetSize(ByRef $oStream, $iNewSize) If Not IsObj($oStream) Then Return SetError(1, 0, 0) Local $iResult = $oStream.SetSize($iNewSize) If @error Or $iResult <> 0 Then Return SetError(2, $iResult, 0) Return 1 EndFunc ;==>_StreamSetSize ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamGetStat ; Description ...: Retrieves stream metadata. ; Syntax ........: _StreamGetStat(ByRef $oStream, ByRef $pStatFlag[, $grfStatFlag]) ; Parameters ....: $oStream - IStream COM object. ; $pStatFlag - [out] Pointer to STATSTG structure. ; $grfStatFlag - [optional] STATFLAG flags (default: $STATFLAG_DEFAULT). ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - Invalid stream object. ; |2 - Memory allocation failed. ; |3 - COM error (HRESULT in @extended). ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Free $pStatFlag with _WinAPI_CoTaskMemFree. ; Related .......: _StreamGetType, _StreamGetName, _StreamGetSize ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-istream-stat ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamGetStat(ByRef $oStream, ByRef $pStatFlag, $grfStatFlag = $STATFLAG_DEFAULT) If Not IsObj($oStream) Then Return SetError(1, 0, 0) Local $iStructSize = DllStructGetSize(DllStructCreate($tagSTATSTG)) Local $pBuffer = _WinAPI_CoTaskMemAlloc($iStructSize) If Not $pBuffer Then Return SetError(2, 0, 0) DllCall("kernel32.dll", "none", "RtlZeroMemory", "ptr", $pBuffer, "ulong_ptr", $iStructSize) Local $iResult = $oStream.Stat($pBuffer, $grfStatFlag) If @error Or $iResult <> 0 Then _WinAPI_CoTaskMemFree($pBuffer) Return SetError(3, $iResult, 0) EndIf $pStatFlag = $pBuffer Return 1 EndFunc ;==>_StreamGetStat ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamGetType ; Description ...: Retrieves stream type from STATSTG structure. ; Syntax ........: _StreamGetType(ByRef $oStream) ; Parameters ....: $oStream - IStream COM object. ; Return values .: Success - Stream type string ("STGTY_STORAGE", "STGTY_STREAM", etc.). ; Failure - Empty string, sets @error: ; |1 - Invalid stream object. ; |2 - Failed to get STATSTG or create structure. ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Uses _StreamGetStat for type retrieval. ; Related .......: _StreamGetStat, _StreamGetName ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-istream-stat ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamGetType(ByRef $oStream) If Not IsObj($oStream) Then Return SetError(1, 0, "") Local $pStat If Not _StreamGetStat($oStream, $pStat, $STATFLAG_DEFAULT) Then Return SetError(2, 0, "") Local $tStat = DllStructCreate($tagSTATSTG, $pStat) If Not IsDllStruct($tStat) Then _WinAPI_CoTaskMemFree($pStat) Return SetError(2, 0, "") EndIf Local $iType = DllStructGetData($tStat, "type") _WinAPI_CoTaskMemFree($pStat) Switch $iType Case $STGTY_STORAGE Return "STGTY_STORAGE" Case $STGTY_STREAM Return "STGTY_STREAM" Case $STGTY_LOCKBYTES Return "STGTY_LOCKBYTES" Case $STGTY_PROPERTY Return "STGTY_PROPERTY" Case Else Return "Unknown" EndSwitch EndFunc ;==>_StreamGetType ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamGetName ; Description ...: Retrieves stream name from STATSTG structure. ; Syntax ........: _StreamGetName(ByRef $oStream) ; Parameters ....: $oStream - IStream COM object. ; Return values .: Success - Stream name string (or empty if none). ; Failure - Empty string, sets @error: ; |1 - Invalid stream object. ; |2 - Failed to get STATSTG or create structure. ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Uses _StreamGetStat for name retrieval. ; Related .......: _StreamGetStat, _StreamGetType ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-istream-stat ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamGetName(ByRef $oStream) If Not IsObj($oStream) Then Return SetError(1, 0, "") Local $pStat If Not _StreamGetStat($oStream, $pStat, $STATFLAG_DEFAULT) Then Return SetError(2, 0, "") Local $tStat = DllStructCreate($tagSTATSTG, $pStat) If Not IsDllStruct($tStat) Then _WinAPI_CoTaskMemFree($pStat) Return SetError(2, 0, "") EndIf Local $sName = "" Local $pName = DllStructGetData($tStat, "pwcsName") If $pName Then $sName = __ReadStreamName($pName) _WinAPI_CoTaskMemFree($pName) EndIf _WinAPI_CoTaskMemFree($pStat) Return $sName EndFunc ;==>_StreamGetName ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamGetSize ; Description ...: Retrieves stream size from STATSTG structure. ; Syntax ........: _StreamGetSize(ByRef $oStream) ; Parameters ....: $oStream - IStream COM object. ; Return values .: Success - Stream size in bytes. ; Failure - 0, sets @error: ; |1 - Invalid stream object. ; |2 - Failed to get STATSTG or create structure. ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Uses _StreamGetStat for size retrieval. ; Related .......: _StreamGetStat, _StreamSetSize ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-istream-stat ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamGetSize(ByRef $oStream) If Not IsObj($oStream) Then Return SetError(1, 0, 0) Local $pStat If Not _StreamGetStat($oStream, $pStat, $STATFLAG_DEFAULT) Then Return SetError(2, 0, 0) Local $tStat = DllStructCreate($tagSTATSTG, $pStat) If Not IsDllStruct($tStat) Then _WinAPI_CoTaskMemFree($pStat) Return SetError(2, 0, 0) EndIf Local $iSize = DllStructGetData($tStat, "cbSize") _WinAPI_CoTaskMemFree($pStat) Return $iSize EndFunc ;==>_StreamGetSize ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamCopyTo ; Description ...: Copies bytes from one stream to another using IStream::CopyTo. ; Syntax ........: _StreamCopyTo(ByRef $oSourceStream, ByRef $pDestStream, $iBytesToCopy, ByRef $iBytesRead, ByRef $iBytesWritten) ; Parameters ....: $oSourceStream - Source IStream COM object. ; $pDestStream - [in/out] Pointer to destination IStream interface. ; $iBytesToCopy - Number of bytes to copy. ; $iBytesRead - [out] Bytes read from source. ; $iBytesWritten - [out] Bytes written to destination. ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - Invalid source stream. ; |2 - Invalid or failed destination stream. ; |3 - COM error (HRESULT in @extended). ; |4 - Failed to set destination stream size. ; |5 - Destination stream not writable. ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Creates new stream if $pDestStream is 0. Release $pDestStream with DllCall("ole32.dll", "ulong", "Release", "ptr", ...). ; Related .......: _StreamRead, _StreamWrite, _StreamSeek ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-istream-copyto ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamCopyTo(ByRef $oSourceStream, ByRef $pDestStream, $iBytesToCopy, ByRef $iBytesRead, ByRef $iBytesWritten) If Not IsObj($oSourceStream) Then Return SetError(1, 0, 0) Local $hGlobal, $bNewStream = False If Not $pDestStream Then $hGlobal = _MemGlobalAlloc($iBytesToCopy, $GMEM_MOVEABLE) If Not $hGlobal Then Return SetError(2, 0, 0) $pDestStream = _WinAPI_CreateStreamOnHGlobal($hGlobal) If Not $pDestStream Then _MemGlobalFree($hGlobal) Return SetError(2, 0, 0) EndIf $bNewStream = True EndIf If Not __COM_IUnknownAddRefPtr($pDestStream) Then If $bNewStream Then _MemGlobalFree($hGlobal) DllCall("ole32.dll", "ulong", "Release", "ptr", $pDestStream) Return SetError(2, 0, 0) EndIf Local $oDestStream = _CreateStreamFromPtr($pDestStream) If Not IsObj($oDestStream) Then If $bNewStream Then _MemGlobalFree($hGlobal) DllCall("ole32.dll", "ulong", "Release", "ptr", $pDestStream) Return SetError(2, 0, 0) EndIf If Not $bNewStream Then Local $pStat If Not _StreamGetStat($oDestStream, $pStat, $STATFLAG_DEFAULT) Then _StreamRelease($oDestStream) DllCall("ole32.dll", "ulong", "Release", "ptr", $pDestStream) Return SetError(2, 0, 0) EndIf Local $tStat = DllStructCreate($tagSTATSTG, $pStat) Local $grfMode = DllStructGetData($tStat, "grfMode") Local $iDestSize = DllStructGetData($tStat, "cbSize") _WinAPI_CoTaskMemFree($pStat) If Not BitAND($grfMode, BitOR($STGM_WRITE, $STGM_READWRITE)) Then _StreamRelease($oDestStream) DllCall("ole32.dll", "ulong", "Release", "ptr", $pDestStream) Return SetError(5, $grfMode, 0) EndIf If $iDestSize < $iBytesToCopy Then If Not _StreamSetSize($oDestStream, $iDestSize + $iBytesToCopy) Then _StreamRelease($oDestStream) DllCall("ole32.dll", "ulong", "Release", "ptr", $pDestStream) Return SetError(4, 0, 0) EndIf EndIf EndIf Local $iResult = $oSourceStream.CopyTo($pDestStream, $iBytesToCopy, $iBytesRead, $iBytesWritten) If @error Or $iResult <> 0 Then _StreamRelease($oDestStream) If $bNewStream Then _MemGlobalFree($hGlobal) DllCall("ole32.dll", "ulong", "Release", "ptr", $pDestStream) Return SetError(3, $iResult, 0) EndIf _StreamRelease($oDestStream) Return 1 EndFunc ;==>_StreamCopyTo ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamCopyToEx ; Description ...: Copies bytes using IStream::Read and IStream::Write. ; Syntax ........: _StreamCopyToEx(ByRef $oSourceStream, ByRef $oDestStream, $iBytesToCopy, ByRef $iBytesRead, ByRef $iBytesWritten) ; Parameters ....: $oSourceStream - Source IStream COM object. ; $oDestStream - Destination IStream COM object. ; $iBytesToCopy - Number of bytes to copy. ; $iBytesRead - [out] Bytes read from source. ; $iBytesWritten - [out] Bytes written to destination. ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - Invalid source stream. ; |2 - Invalid destination stream. ; |3 - Failed to get source stream size. ; |4 - Failed to get destination stream size. ; |5 - Failed to set destination stream size. ; |6 - Failed to seek source stream. ; |7 - Failed to read from source stream. ; |8 - Failed to seek destination stream. ; |9 - Failed to write to destination stream. ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Resizes destination stream to append copied bytes. ; Related .......: _StreamRead, _StreamWrite, _StreamSeek ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nn-objidl-istream ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamCopyToEx(ByRef $oSourceStream, ByRef $oDestStream, $iBytesToCopy, ByRef $iBytesRead, ByRef $iBytesWritten) If Not IsObj($oSourceStream) Then Return SetError(1, 0, 0) If Not IsObj($oDestStream) Then Return SetError(2, 0, 0) Local $iDestStreamSize = _StreamGetSize($oDestStream) If @error Then Return SetError(4, @extended, 0) If $iDestStreamSize < $iDestStreamSize + $iBytesToCopy Then If Not _StreamSetSize($oDestStream, $iDestStreamSize + $iBytesToCopy) Then Return SetError(5, @extended, 0) EndIf EndIf If _StreamSeek($oSourceStream, 0, $STREAM_SEEK_SET) <> 0 Then Return SetError(6, @extended, 0) Local $pSrcMemRead _StreamRead($oSourceStream, $iBytesToCopy, $pSrcMemRead, $iBytesRead) If @error Then If $pSrcMemRead Then _MemGlobalFree($pSrcMemRead) Return SetError(7, @extended, 0) EndIf If $iBytesRead < $iBytesToCopy Then _MemGlobalFree($pSrcMemRead) Return SetError(7, 0, 0) EndIf If _StreamSeek($oDestStream, $iDestStreamSize, $STREAM_SEEK_SET) <> $iDestStreamSize Then _MemGlobalFree($pSrcMemRead) Return SetError(8, @extended, 0) EndIf _StreamWrite($oDestStream, $pSrcMemRead, $iBytesToCopy, $iBytesWritten, False) _MemGlobalFree($pSrcMemRead) If @error Then Return SetError(9, @extended, 0) If $iBytesWritten < $iBytesToCopy Then Return SetError(9, 0, 0) Return 1 EndFunc ;==>_StreamCopyToEx ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamClone ; Description ...: Creates a new stream with its own seek pointer. ; Syntax ........: _StreamClone(ByRef $oStream, ByRef $pStream) ; Parameters ....: $oStream - IStream COM object. ; $pStream - [out] Pointer to cloned IStream interface. ; Return values .: Success - Cloned IStream COM object. ; Failure - 0, sets @error: ; |1 - Invalid stream object. ; |2 - COM error (HRESULT in @extended). ; |3 - Failed to create COM object. ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Release returned object with _StreamRelease and pointer with DllCall("ole32.dll", "ulong", "Release", "ptr", ...). ; Related .......: _StreamRead, _StreamSeek ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-istream-clone ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamClone(ByRef $oStream, ByRef $pStream) If Not IsObj($oStream) Then Return SetError(1, 0, 0) Local $iResult = $oStream.Clone($pStream) If @error Or $iResult <> 0 Then Return SetError(2, $iResult, 0) Local $oClone = ObjCreateInterface($pStream, $sIID_IStream, $tagIStream) If Not IsObj($oClone) Then DllCall("ole32.dll", "ulong", "Release", "ptr", $pStream) Return SetError(3, 0, 0) EndIf Return $oClone EndFunc ;==>_StreamClone ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamLockRegion ; Description ...: Restricts access to a stream region. ; Syntax ........: _StreamLockRegion(ByRef $oStream, $iOffset, $iLength, $dwLockType) ; Parameters ....: $oStream - IStream COM object. ; $iOffset - Starting offset of region. ; $iLength - Length of region. ; $dwLockType - Lock type (e.g., $LOCK_EXCLUSIVE). ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - Invalid stream object. ; |2 - COM error (HRESULT in @extended). ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Not supported by all streams (e.g., memory streams return STG_E_INVALIDFUNCTION). ; Related .......: _StreamUnlockRegion ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-istream-lockregion ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamLockRegion(ByRef $oStream, $iOffset, $iLength, $dwLockType) If Not IsObj($oStream) Then Return SetError(1, 0, 0) Local $iResult = $oStream.LockRegion($iOffset, $iLength, $dwLockType) If @error Or $iResult <> 0 Then Return SetError(2, $iResult, 0) Return 1 EndFunc ;==>_StreamLockRegion ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamUnlockRegion ; Description ...: Removes a previously set lock. ; Syntax ........: _StreamUnlockRegion(ByRef $oStream, $iOffset, $iLength, $dwLockType) ; Parameters ....: $oStream - IStream COM object. ; $iOffset - Starting offset of region. ; $iLength - Length of region. ; $dwLockType - Lock type to remove. ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - Invalid stream object. ; |2 - COM error (HRESULT in @extended). ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Parameters must match _StreamLockRegion. ; Related .......: _StreamLockRegion ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-istream-unlockregion ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamUnlockRegion(ByRef $oStream, $iOffset, $iLength, $dwLockType) If Not IsObj($oStream) Then Return SetError(1, 0, 0) Local $iResult = $oStream.UnlockRegion($iOffset, $iLength, $dwLockType) If @error Or $iResult <> 0 Then Return SetError(2, $iResult, 0) Return 1 EndFunc ;==>_StreamUnlockRegion ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamCommit ; Description ...: Flushes data to the underlying medium. ; Syntax ........: _StreamCommit(ByRef $oStream[, $grfCommitFlags]) ; Parameters ....: $oStream - IStream COM object. ; $grfCommitFlags - [optional] Commit flags (default: $STGC_DEFAULT). ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - Invalid stream object. ; |2 - COM error (HRESULT in @extended). ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Used for transacted streams to make changes permanent. ; Related .......: _StreamWrite, _StreamRevert ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-istream-commit ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamCommit(ByRef $oStream, $grfCommitFlags = $STGC_DEFAULT) If Not IsObj($oStream) Then Return SetError(1, 0, 0) Local $iResult = $oStream.Commit($grfCommitFlags) If @error Or $iResult <> 0 Then Return SetError(2, $iResult, 0) Return 1 EndFunc ;==>_StreamCommit ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamRevert ; Description ...: Discards changes since the last commit. ; Syntax ........: _StreamRevert(ByRef $oStream) ; Parameters ....: $oStream - IStream COM object. ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - Invalid stream object. ; |2 - COM error (HRESULT in @extended). ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Only for transacted streams; memory streams return STG_E_INVALIDFUNCTION. ; Related .......: _StreamCommit ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-istream-revert ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamRevert(ByRef $oStream) If Not IsObj($oStream) Then Return SetError(1, 0, 0) Local $iResult = $oStream.Revert() If @error Or $iResult <> 0 Then Return SetError(2, $iResult, 0) Return 1 EndFunc ;==>_StreamRevert ; #FUNCTION# ==================================================================================================================== ; Name ..........: _StreamQueryInterface ; Description ...: Retrieves a pointer to a supported interface. ; Syntax ........: _StreamQueryInterface(ByRef $oStream, $sIID) ; Parameters ....: $oStream - IStream COM object. ; $sIID - Interface ID (GUID) as string. ; Return values .: Success - Pointer to requested interface. ; Failure - 0, sets @error: ; |1 - Invalid stream object. ; |2 - Invalid IID. ; |3 - QueryInterface failed (HRESULT in @extended). ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Release pointer with DllCall("ole32.dll", "ulong", "Release", "ptr", ...). ; Related .......: _StreamRelease, _CreateStreamFromPtr ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/unknwn/nf-unknwn-iunknown-queryinterface ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StreamQueryInterface(ByRef $oStream, $sIID) If Not IsObj($oStream) Then Return SetError(1, 0, 0) If Not IsString($sIID) Or $sIID = "" Then Return SetError(2, 0, 0) Local $tIID = _WinAPI_GUIDFromString($sIID) Local $pInterface Local $iResult = $oStream.QueryInterface(DllStructGetPtr($tIID), $pInterface) If @error Or $iResult <> 0 Or Not $pInterface Then Return SetError(3, $iResult, 0) Return $pInterface EndFunc ;==>_StreamQueryInterface ; #FUNCTION# ==================================================================================================================== ; Name ..........: _WinAPI_GetBufferData ; Description ...: Retrieves data from a memory buffer as a binary string. ; Syntax ........: _WinAPI_GetBufferData($pBuffer[, $iLength]) ; Parameters ....: $pBuffer - Pointer to memory buffer. ; $iLength - [optional] Size of data to retrieve (default: entire buffer). ; Return values .: Success - Binary string of buffer data. ; Failure - 0, sets @error to 1 (invalid buffer). ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Converts read stream data to binary string. ; Related .......: _StreamRead, _StreamCreateMemoryBuffer ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalalloc ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _WinAPI_GetBufferData($pBuffer, $iLength = 0) If Not _WinAPI_IsMemory($pBuffer) Then Return SetError(1, 0, 0) If Not $iLength Then $iLength = _WinAPI_GetMemorySize($pBuffer) Local $tData = DllStructCreate("byte[" & $iLength & "]", $pBuffer) Return DllStructGetData($tData, 1) EndFunc ;==>_WinAPI_GetBufferData ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: _StatDisplay ; Description ...: Displays STATSTG structure metadata. ; Syntax ........: _StatDisplay($pStat) ; Parameters ....: $pStat - Pointer to STATSTG structure. ; Return values .: Success - 1 ; Failure - 0, sets @error: ; |1 - Invalid STATSTG pointer. ; |2 - Failed to create STATSTG structure. ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Frees pwcsName field of STATSTG structure. ; Related .......: _StreamGetStat, __ReadStreamName ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/stg/statstg ; Example .......: See Example_IStream. ; =============================================================================================================================== Func _StatDisplay($pStat) If Not $pStat Then Return SetError(1, 0, 0) Local $tStat = DllStructCreate($tagSTATSTG, $pStat) If Not IsDllStruct($tStat) Then Return SetError(2, 0, 0) Local $sOutput = "", $pName = DllStructGetData($tStat, "pwcsName") Local $sName = $pName ? __ReadStreamName($pName) : "N/A" If $pName Then _WinAPI_CoTaskMemFree($pName) $sOutput &= "Name: " & $sName & @CRLF Local $iType = DllStructGetData($tStat, "type") Switch $iType Case $STGTY_STORAGE $sOutput &= "Type: STGTY_STORAGE" & @CRLF Case $STGTY_STREAM $sOutput &= "Type: STGTY_STREAM" & @CRLF Case $STGTY_LOCKBYTES $sOutput &= "Type: STGTY_LOCKBYTES" & @CRLF Case $STGTY_PROPERTY $sOutput &= "Type: STGTY_PROPERTY" & @CRLF Case Else $sOutput &= "Type: Unknown" & @CRLF EndSwitch $sOutput &= "Size: " & DllStructGetData($tStat, "cbSize") & " bytes" & @CRLF Local $tFileTime = DllStructCreate("dword low;dword high") DllStructSetData($tFileTime, "low", DllStructGetData($tStat, "mtime_low")) DllStructSetData($tFileTime, "high", DllStructGetData($tStat, "mtime_high")) $sOutput &= "Modified: " & _Date_Time_FileTimeToStr($tFileTime, 1) & @CRLF DllStructSetData($tFileTime, "low", DllStructGetData($tStat, "ctime_low")) DllStructSetData($tFileTime, "high", DllStructGetData($tStat, "ctime_high")) $sOutput &= "Created: " & _Date_Time_FileTimeToStr($tFileTime, 1) & @CRLF DllStructSetData($tFileTime, "low", DllStructGetData($tStat, "atime_low")) DllStructSetData($tFileTime, "high", DllStructGetData($tStat, "atime_high")) $sOutput &= "Accessed: " & _Date_Time_FileTimeToStr($tFileTime, 1) & @CRLF $sOutput &= "Mode: 0x" & Hex(DllStructGetData($tStat, "grfMode"), 8) & @CRLF $sOutput &= "Locks Supported: 0x" & Hex(DllStructGetData($tStat, "grfLocksSupported"), 8) & @CRLF Local $tCLSID = DllStructCreate("byte[16]", DllStructGetPtr($tStat, "clsid")) $sOutput &= "CLSID: " & _WinAPI_StringFromGUID($tCLSID) & @CRLF $sOutput &= "State Bits: 0x" & Hex(DllStructGetData($tStat, "grfStateBits"), 8) & @CRLF ConsoleWrite($sOutput) Return 1 EndFunc ;==>_StatDisplay ; #INTERNAL_USE_ONLY# =========================================================================================================== Func __COM_IUnknownAddRef($vObject) Local $tagVARIANT = "word vt;word r1;word r2;word r3;ptr data;ptr reserved;" Local Const $PTR_SIZE = DllStructGetSize(DllStructCreate('ptr')) Local Const $VT_UINT = 0x0017 Local $sType = IsObj($vObject) ? "idispatch" : "ptr" Local $tVariant = DllStructCreate($tagVARIANT) DllCall("oleaut32.dll", "long", "VariantInit", "ptr", DllStructGetPtr($tVariant)) Local $aCall = DllCall("oleaut32.dll", "long", "DispCallFunc", _ $sType, $vObject, "dword", $PTR_SIZE, "dword", 4, "dword", $VT_UINT, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVariant)) If @error Or $aCall[0] Then Return SetError(1, 0, 0) Return DllStructGetData(DllStructCreate("dword", DllStructGetPtr($tVariant, "data")), 1) EndFunc ;==>__COM_IUnknownAddRef ; #INTERNAL_USE_ONLY# =========================================================================================================== Func __COM_IUnknownAddRefPtr($pStream) If Not $pStream Then Return SetError(1, 0, 0) Local $oStream = ObjCreateInterface($pStream, $IID_IStream, $tagIStream) If Not IsObj($oStream) Then Return SetError(2, 0, 0) Local $iRef = $oStream.AddRef() $iRef = $oStream.AddRef() If @error Or Not $iRef Then Return SetError(3, 0, 0) _StreamRelease($oStream) Return $iRef EndFunc ;==>__COM_IUnknownAddRefPtr ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __ReadStreamName ; Description ...: Reads Unicode name from STATSTG structure. ; Syntax ........: __ReadStreamName($pName) ; Parameters ....: $pName - Pointer to Unicode string (LPOLESTR). ; Return values .: Success - Stream name string. ; Failure - Empty string, sets @error to 1 (invalid pointer). ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Used by _StreamGetName and _StatDisplay. ; Related .......: _StreamGetName, _StreamGetStat ; Link ..........: https://docs.microsoft.com/en-us/windows/win32/stg/statstg ; Example .......: See Example_IStream. ; =============================================================================================================================== ; Continuation of IStream UDF ; Starting from the end of __ReadStreamName function Func __ReadStreamName($pName) If Not $pName Then Return SetError(1, 0, "") Local $iLen = _WinAPI_StrLen($pName) If Not $iLen Then Return "" Local $tName = DllStructCreate("wchar[" & ($iLen + 1) & "]", $pName) Return DllStructGetData($tName, 1) EndFunc ;==>__ReadStreamName ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name ..........: __IStreamErrorInfo ; Description ...: Displays error information for HRESULT codes. ; Syntax ........: __IStreamErrorInfo($iError, $sFunction) ; Parameters ....: $iError - HRESULT error code. ; $sFunction - Name of the function where error occurred. ; Return values .: None ; Author ........: Numeric1 ; Modified ......: 2025-08-10 ; Remarks .......: Outputs error details to console for debugging. ; Related .......: _IStream_GetErrorInfo ; Example .......: See Example_IStream. ; =============================================================================================================================== Func __IStreamErrorInfo($iError, $sFunction) Local $aError = _IStream_GetErrorInfo($iError) If @error Then ConsoleWrite("Error in " & $sFunction & ": Unknown HRESULT 0x" & Hex($iError, 8) & @CRLF) Else ConsoleWrite("Error in " & $sFunction & ": " & $aError[0] & " - " & $aError[1] & " (" & $aError[2] & ")" & @CRLF) EndIf EndFunc ;==>__IStreamErrorInfo