App needed to the development of portable apps

Discuss anything related to portable freeware here.
Post Reply
Message
Author
castman
Posts: 179
Joined: Sat Jun 28, 2008 5:41 am
Location: Brazil, Sao Paulo
Contact:

App needed to the development of portable apps

#1 Post by castman » Thu Jul 23, 2009 5:38 am

The Big Problem IS: Portable Application developing needs a 'freeware/open source' in order to edit .reg files without importing them.

We need something to edit sucessfully the registry file paths displayed inside the .reg files in REG_MULTI_SZ, REG_EXPAND_SZ and REG_BINARY.

That would enable going further at the developing of portable apps.

Edit: I am going to develop a NT 5 .reg file wizard to convert such values to standard string, susbtitute the file paths, reconvert and save to a new .reg file. I chose AutoIt for it. This may take a long time.

There is some NT5 .reg file specifications:

1. Each continue line from a value of such kind of values starts with 2 spaces
2. My Program will need to give warnings about key and value names longer than 255 characters
Edit3: 3. The number of characters doesn't matter for merging.
Edit4: 4. Each registry value character spends 4 houses the same way that hexadecimal stands for unicode chars, except for REG_BINARY values
Edit4: 5. Each line from such values, except for the registry key and the 1st line of a value, goes to the maximum of 78 characters
Edit4: 6. REG_MULTI_SZ values always ends with eight zeros.
Edit4: 7. REG_BINARY values will accept two modes: dot separated or not.
Edit5: 8. In one continue line of 78 columns you can place 12 and a middle ANSI characters

Edit6:

The license of my application is going to be an open source license.

I am planning to do an understable application. I say that because I did not understand the winpenpack autoit source code.

Edit7: I was thinking about how can I put all this into arrays without repeating strings, then I had the idea of dimensional loops to categorize the arrays.

$keyname and $valuesperkey are 1st dimension
$valuename, $linescount, $modifiedvalues and $pathspervalue are 2nd dimension
$filepaths, $paths, $pathkind and $separator (I am thinking about removing these two last) are 3rd dimension

LIKE

Code: Select all

for $k = 1 to UBound($keyname)
 for 1 to $valuesperkey[$k]
  $v = $v + 1
  for 1 to $pathspervalue[$v]
   $p = $p + 1
;filereadline from tempfile and $modifiedvalues replace
  next
;knowledge only after further tests
 next
next
I will need to rewrite my code later.
Last edited by castman on Tue Aug 11, 2009 1:12 pm, edited 7 times in total.
I AM,YOU ARE,WE ARE WHEN WE ARE RIGHT. emucr,softpedia,and HokutoNoKen and Speakonia on YT

User avatar
m^(2)
Posts: 890
Joined: Sat Mar 31, 2007 2:38 am
Location: Kce,PL
Contact:

Re: App needed to the development of portable apps

#2 Post by m^(2) » Wed Jul 29, 2009 7:58 am

Jauntized regedit will do the trick.

castman
Posts: 179
Joined: Sat Jun 28, 2008 5:41 am
Location: Brazil, Sao Paulo
Contact:

Re: App needed to the development of portable apps

#3 Post by castman » Wed Jul 29, 2009 5:49 pm

:D I'm almost done with the app

Explaining what I did:

I want to recognize a file protocol path like this: X:\ and like this X:\something.
I also want to recognize a file protocol path like this: %ProGraMFiles%\something and: %APpDaTa%\something and: %Localsettings%\something and: %winDIR%\something
I also want to recognize a UNC path like this: \\something and: \\something\something2
I also want to recognize the end of the file paths, like this: \something.ext
Off course, all file paths may contain spaces. And That's all.

My BIG Problem is: How can I edit files using AutoIt and avoid rewriting a file from scratch?

Here is my source code: :wink:

Reedition1:
Reedition2:
Reedition3:
Reedition4:
Reedition5:
Reedition6:
Reedition7:
Reedition8:

Code: Select all

#include <File.au3>

AutoItSetOption("MustDeclareVars", 1)

Dim $keyname[5000], $valuename[5000], $modifiedvalues[5000], $paths[5000], $filepaths[5000]
Dim $tkey, $tvname, $tvalue, $separator, $pathkind[5000], $lnc[5000], $separators[5000], $TempString[10000], $TmpString[2] 
Dim $pathnumber = 0, $r, $c, $d = 0, $output = "", $k, $v, $ln = 0, $pattern[10]
Dim $mode, $answer, $file, $line, $result, $result2, $result3
$pattern[0] = "[[:alpha:]]\x3A\x5C[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x3B\x20]*"
$pattern[1] = "\x5C\x5C[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x20\x3B]*"
$pattern[2] = "\x25(?i)programfiles\x25\x5C(?-i)[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x3B\x20]*"
$pattern[3] = "\x25(?i)commonprogramfiles\x25\x5C(?-i)[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x3B\x20]*"
$pattern[4] = "\x25(?i)programfiles\x25\x5C(?-i)[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x3B\x20]*"
$pattern[5] = "\x25(?i)windir\x25\x5C(?-i)[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x3B\x20]*"
$pattern[6] = "\x25(?i)systemroot\x25\x5C(?-i)[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x3B\x20]*"
$pattern[7] = "\x25(?i)appdata\x25\x5C(?-i)[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x3B\x20]*"
$pattern[8] = "\x25(?i)userprofile\x25\x5C(?-i)[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x3B\x20]*"
$pattern[9] = "\x25(?i)allusersprofile\x25\x5C(?-i)[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x3B\x20]*"
$answer = MsgBox(4, "What kind of value you want to convert ?", "REG_EXPAND_SZ or REG_MULTI_SZ ?")
If $answer = 7 Then
	$mode = "REG_MULTI_SZ"
else
	$mode = "REG_EXPAND_SZ"
EndIf
MsgBox(0,"Mode",$mode)
$file = FileOpen("file.reg", 0)

; Check if file opened for reading OK
If $file = -1 Then
	MsgBox(0, "Error", "Unable to open file.")
	Exit
EndIf
; Read in lines of text until the EOF is reached
Func AssignPaths($d)
	For $c = 0 to (UBound($TempString,1)) - 1
	       	$pathnumber = $pathnumber + 1
		$keyname[$pathnumber] = $tkey
		$valuename[$pathnumber] = $tvname
		If $TempString[$c] <> "" Then
		$tvalue	= StringRight($TempString[$c],1)
		endif
		If $tvalue = chr(34) or $tvalue = "," or $tvalue = " " or ";" then
			$tvalue = StringTrimRight($TempString[$c],1)
			$separators[$pathnumber] = StringRight($TempString[$c],1)	
			$filepaths[$pathnumber] = StringTrimRight($TempString[$c],1)
		Else
			$tvalue = $TempString[$c]
			$filepaths[$pathnumber] = $TempString[$c]
		EndIf
		$TmpString = StringRegExp($tvalue,"[^\x2E\x22\x2C]*\x5C",1)
		If UBound($TmpString,1) <> 0 Then
		$tvalue = $TmpString[0]
		endif
		$paths[$pathnumber] = $tvalue
		$modifiedvalues[$pathnumber] = $output
		$lnc[$pathnumber] = $ln
		$pathkind[$pathnumber] = $d
		MsgBox(0,"hi",$paths[$pathnumber])
	Next	
EndFunc
While 1
        $line = FileReadLine($file)
        If @error = -1 Then ExitLoop
	$result = StringInStr($line, "[HKEY_")
        if $result <> 0 then $tkey = $line
	if $mode = "REG_EXPAND_SZ" then
		$result = StringInStr($line, "=hex(2):")
	else
		$result = StringInStr($line, "=hex(7):")
	endif
        if $result<>0 then
        	$tvname = StringLeft($line,$result-1)
		$result = StringInStr($line, chr(34)&"=")
		$result2 = StringTrimLeft($line,$result+8)
		$result = StringInStr($result2,chr(44)&chr(92))
		if $result = StringInStr($result2,",\") <> 0 then        
		While $result <> 0
			$ln = $ln + 1
			$result2 = StringTrimRight($result2,1)
			$result3 = StringTrimLeft(FileReadLine($file),2)
			$result2 = $result2 & $result3
			$result = StringInStr($result2,",\")
		Wend
        	else 
			$ln = 1
		endif
	$TempString = StringSplit($result2,",")
        For $c = 1 to (UBound($TempString,1)) - 1
        If $TempString[$c] = "00" Then
		$d = $d + 1
		If $d = 2 then $output = $output & @CRLF
	EndIf
	If $TempString[$c] <> "00" Then
                $output = $output & chr(dec($TempString[$c]))
		$d = $d - 1
	Endif
        Next
	$d = 10
	$TempString = StringRegExp($output,"[[:alpha:]]\x3A\x5C[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x3B\x20]*[\x22\x2C\x20\x3B\x3A]?",3)
	if UBound($TempString,1) <> 0 then
		AssignPaths(0)
	endif
        $TempString = StringRegExp($output,"\x5C\x5C[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x20\x3B]*[\x22\x2C\x20\x3B\x3A]?",3)
	if UBound($TempString,1) <> 0 then
		AssignPaths(1)
	endif
        $TempString = StringRegExp($output,"\x25(?i)programfiles\x25\x5C(?-i)[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x3B\x20]*[\x22\x2C\x20\x3B\x3A]?",3)
	$c = @error
	$r = @extended
		MsgBox(0,"hi",$c&$r)
		AssignPaths(2)
	$TempString = StringRegExp($output,"\x25(?i)commonprogramfiles\x25\x5C[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x3B\x20]*[\x22\x2C\x20\x3B\x3A]?",3)
	if UBound($TempString,1) <> 0 then
		AssignPaths(3)
	endif
        $TempString = StringRegExp($output,"\x25(?i)windir\x25\x5C(?-i)[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x3B\x20]*[\x22\x2C\x20\x3B\x3A]?",3)
	if UBound($TempString,1) <> 0 then
		AssignPaths(4)
	endif
	$TempString = StringRegExp($output,"\x25(?i)systemroot\x25\x5C(?-i)[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x3B\x20]*[\x22\x2C\x20\x3B\x3A]?",3)
	if UBound($TempString,1) <> 0 then
		AssignPaths(5)
	endif
	$TempString = StringRegExp($output,"\x25(?i)appdata\x25\x5C(?-i)[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x3B\x20]*[\x22\x2C\x20\x3B\x3A]?",3)
	if UBound($TempString,1) <> 0 then
		AssignPaths(6)
	endif
	$TempString = StringRegExp($output,"\x25(?i)userprofile\x25\x5C(?-i)[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x3B\x20]*[\x22\x2C\x20\x3B\x3A]?",3)
	if UBound($TempString,1) <> 0 then
		AssignPaths(7)
	endif
	$TempString = $TempString = StringRegExp($output,"\x25(?i)allusersprofile\x25\x5C(?-i)[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x3B\x20]*[\x22\x2C\x20\x3B\x3A]?",3)
	if UBound($TempString,1) <> 0 then
		AssignPaths(8)
	endif
	$TempString = StringRegExp($output,"\x25(?i)systemdrive\x25\x5C(?-i)[^\x2E\x22\x2C\x5C\x3A\x3B][^\x2E\x22\x2C\x3A\x3B]*\x5C[^\x2E\x22\x2C\x5C\x3A\x3B]*\x2E[^\x2E\x22\x2C\x5C\x3A\x3B\x20]*[\x22\x2C\x20\x3B\x3A]?",3)
	if UBound($TempString,1) <> 0 then
		AssignPaths(9)
	endif
	endif
Wend

FileClose($file)
$output = FileSaveDialog( "Choose a name.", @ScriptDir, "Temp File (*.tmp)", 2)
If @error Then Exit
MsgBox(4096,"","You chose " & $output&".tmp")
$file = FileOpen($output&".tmp", 1)
; Check if file opened for writing OK
If $file = -1 Then
	MsgBox(0, "Error", "Unable to open file.")
	Exit
EndIf
For $c = 1 to $pathnumber
	FileWriteLine($file,$paths[$c])
	MsgBox(0,$paths[$c],$paths[$c])
Next
FileClose($file)

Run("Notepad.exe "&chr(34)&$output&".tmp"&chr(34))
$d = @error
MsgBox(0,"Edit the output file and Confirm",chr(34)&$output&".tmp"&chr(34)&$d)
$file = FileOpen($output&".tmp", 0)
; Check if file opened for writing OK
If $file = -1 Then
	MsgBox(0, "Error", "Unable to open file.")
	Exit
EndIf
For $c = 1 to $pathnumber
	$line = FileReadLine($file)
	If @error = -1 Then Exit
	MsgBox(0,"hi",$line&$paths[$c])
	$d = @error
	$v = @extended
	$output = StringReplace($filepaths[$c],$paths[$c],$line,1)
	MsgBox(0,"hi",$output&$d&$v&$filepaths[$c])
	$r = $pathkind[$c]
	Select
	case $separators[$c] = ","
		$separator = "\x2C"
	case $separators[$c] = " "
		$separator = "\x20"
	case $separators[$c] = ";"
		$separator = "\x3B"
	case $separators[$c] = chr(34)
		$separator = "\x22"
	EndSelect
	$result2 = StringReplace($modifiedvalues[$c],$filepaths[$c],$output)
	$filepaths[$c] = $output
	$paths[$c] = $line
	if $modifiedvalues[$c] = $modifiedvalues[$c+1] then
		$modifiedvalues[$c] = $output
		$modifiedvalues[$c+1] = $modifiedvalues[$c]
	endif
	$d = @error
	$v = @extended
	MsgBox(0,"hi",$modifiedvalues[$c]&$d&$v)
Next
FileClose($file)
MsgBox(0,"Replace","OK")
$file = FileOpen("file.reg", 0)

; Check if file opened for reading OK
If $file = -1 Then
	MsgBox(0, "Error", "Unable to open file.")
	Exit
EndIf
For $c = 1 to $pathnumber
	$line = FileReadLine($file)
	If @error = -1 Then ExitLoop
	$lc = $lc + 1
	If $line = $keyname[$c] Then $tkey = $line
	if $mode = "REG_EXPAND_SZ" then
		$result = StringInStr($line, "=hex(2):")
	else
		$result = StringInStr($line, "=hex(7):")
	endif
	if $result <> 0 then
	$tvname = StringLeft($line,$result-1)
	if $tvname = $valuename[$c] then
		$TempString = StringSplit($paths[$c],"")
		_FileWriteToLine($file,$lc,$sText,1)
	endif
	endif
Next
Edit1: Now, I will probably finish this code with this function: _FileWriteToLine($file,$lc,$sText,1). I need to continue it in the next day.
Last edited by castman on Tue Aug 11, 2009 11:30 am, edited 11 times in total.
I AM,YOU ARE,WE ARE WHEN WE ARE RIGHT. emucr,softpedia,and HokutoNoKen and Speakonia on YT

crownixx
Posts: 403
Joined: Sat May 12, 2007 6:26 am

Re: App needed to the development of portable apps

#4 Post by crownixx » Thu Jul 30, 2009 6:06 pm

castman wrote:The Big Problem IS: Portable Application developing needs a 'freeware/open source' in order to edit .reg files without importing them.

We need something to edit successfully the registry file paths displayed inside the .reg files in REG_MULTI_SZ, REG_EXPAND_SZ and REG_BINARY.
The objective is clear but why changing the values inside the .reg files if you are not importing them (temporarily for portable application) ?

AFAIK, there are 2 portable launcher and you only need to edit *.ini file (which of course this source is open and can be read by anyone). Both portable launcher are open source too. If i'm right, they modify the .reg file first before importing it into the system temporarily. You might want to look at part of their module.There are
1. X-Launcher. Develop by Winpenpack team using Autoit language (maybe this interest you). Have their own portable platform (the suggested directory structure)
2. Chris's PortableApps.com Launcher. Develop by Chriss using NSIS language. Design to use Portableapps.com platform (the suggested directory structure).
JauntePE the portable maker: <<JauntePE Google Site >>

castman
Posts: 179
Joined: Sat Jun 28, 2008 5:41 am
Location: Brazil, Sao Paulo
Contact:

Re: App needed to the development of portable apps

#5 Post by castman » Sun Aug 02, 2009 5:44 pm

crownixx wrote:
castman wrote:The Big Problem IS: Portable Application developing needs a 'freeware/open source' in order to edit .reg files without importing them.

We need something to edit successfully the registry file paths displayed inside the .reg files in REG_MULTI_SZ, REG_EXPAND_SZ and REG_BINARY.
The objective is clear but why changing the values inside the .reg files if you are not importing them (temporarily for portable application) ?

AFAIK, there are 2 portable launcher and you only need to edit *.ini file (which of course this source is open and can be read by anyone). Both portable launcher are open source too. If i'm right, they modify the .reg file first before importing it into the system temporarily. You might want to look at part of their module.There are
1. X-Launcher. Develop by Winpenpack team using Autoit language (maybe this interest you). Have their own portable platform (the suggested directory structure)
2. Chris's PortableApps.com Launcher. Develop by Chriss using NSIS language. Design to use Portableapps.com platform (the suggested directory structure).
Thanks! I may take a look. The biggest use of this approach is portabilizing applications like JRE and Visual C++ 2005 Runtime that need the edition of REG_EXPAND_SZ values. John T. Haller said that couldn't fully portabilize Java and I proving that it's possible (Maybe not without Administrator Rights).

@m(2) Batch replacing file paths ? With regedit.exe you waste a lot of time to do something like that.
I AM,YOU ARE,WE ARE WHEN WE ARE RIGHT. emucr,softpedia,and HokutoNoKen and Speakonia on YT

castman
Posts: 179
Joined: Sat Jun 28, 2008 5:41 am
Location: Brazil, Sao Paulo
Contact:

One Unfinished Problem blocked me from going further

#6 Post by castman » Mon Aug 10, 2009 4:55 pm

My Problem is with this line

Code: Select all

$TempString = StringRegExp($output,"\x25(?i)programfiles\x25\x5C(?-i)[^\x2E\x22\x2C\x5C\x3A][^\x2E\x22\x2C\x3A]*\x5C[^\x2E\x22\x2C\x5C\x3A]*\x2E[^\x2E\x22\x2C\x5C\x3A]*[\x22\x2C\x20\x3B]?",1)
By some reason the pattern isn't returning more than one result!! Try this line:

Code: Select all

%ProGraMFileS%\EI\File.ext %ProGraMFileS%\EIXI\File1.ext
I Already fixed this time... =P

Now I'm stuck into this line:

Code: Select all

$line = FileReadLine($file)
Exactly, by some reason the file I temporarily created isn't being read. The file is placed under C:\Documents and Settings\User\My documents\Folder. Now this looks bizarre.

I discovered what was wrong, I had to set FileOpen with the 0 parameter, like: $file = FileOpen($output&".tmp", 0).

Now I'm stuck into this line:

Code: Select all

$output = StringRegExpReplace($filepaths[$c],"([^\x2E\x22\x2C\x3B]*\x5C)",$paths[$c],0)
Try it with this value:

Code: Select all

C:\Documénts ând Sàttings\BRAR\FOOT.ext"
Imagining you substitute this folder name BRAR to BRA789, it becomes

Code: Select all

C:Documénts ând SàttingsBRA789FOOT.ext"
Why this StringRegExpReplace is Eating the backslashes ??

I substituted this line by:

Code: Select all

$output = StringRegExpReplace($filepaths[$c],"[^\x2E\x22\x2C\x3B]*\z\x5C",$paths[$c],0)
And it worked! Now I'm stucked in the next line:

Code: Select all

$modifiedvalues[$c] = StringRegExpReplace($modifiedvalues[$c],$pattern[$r]&$separator,$filepaths[$c], 1)
The concept is harder now. The modified value may have two different file paths with similar patterns. I supposed I have to think more!
Same behavior to solve.[/i]

Edit: I thought it had work but it didn't. However, I realized that I didn't need to use StringRegExpReplace, StringReplace satisfied my needs.

The RegExp Noobie >_< can take some rest now!
I AM,YOU ARE,WE ARE WHEN WE ARE RIGHT. emucr,softpedia,and HokutoNoKen and Speakonia on YT

Post Reply