Skip to content
⌘ NSIS Forum Archive

File owner & permission

11 posts

dogo#

File owner & permission

Hello forum,

I have got a big problem with NSIS.

I use AdvReplaceInFile to replace some strings in my file I would like to change.
This works great. After all actions I set my file permissions with AccessControll Plugin, but the permissions and the file owner will not be set correctly.

I suppose so that the temporary file (that will be copied over original) that will be created with AdvReplaceInFile does not get the file permissions from AccessControll Plugin.

Is there any workaround or something I does not know ?!
dogo#
Hello kichik,

yes of course, first I replace in some files, after that I
change the file privileges.

The strange thing is that all files which were not substituted with some new text have the privileges I set. All with replaced text contain privileges like new created files within this account installer run in.

Greetings,

Wolfgang.
kichik#
Well, usually what this kind of functions do is create a new file and write the new data into it. You could either change that script to create the file in the correct folder, or do the replacement in another file and later manually copy the contents into the old file.
dogo#
Hello kichik,

I think this will do what I want, but isn`t it a little bit strange that the
AccessControl Plugin will not change new file attributes which are (should ?) created befor changing attributes ?

This seems to be a bug for me. 😢
Looks like NSIS will copy the temporary files at the end of the installer
over my orginal ? 🤪

The question for me is, if this is an NSIS or an Plugin problem.

Greetings,

Wolfgang.
kichik#
Looks like NSIS will copy the temporary files at the end of the installer over my orginal?
As I said, that's what those replacement scripts usually do. It's a problem with the script.
dogo#
Hello kichik,

yes that is right, but the replacement script calls the rename statement within his replace function. Shouldn`t NSIS rename the file when this statment is called !? For me looks this like NSIS renaming all files at the end of the install time. But not at this time where rename is called !? I am a little bit confused now.
kichik#
Rename renames immediately. The problem is that the temporary files it renames is either created in the temporary folder and therefore gets a different set of privileges, or the destination file has privileges different than even those of the folder that contains it.
dogo#
Hi,

but shouldn`t work set file privileges as expected in your case ?!
I am right that renames copy the temp file to my $INSTDIR ?

Flow Diagram:

OriginalFile -> ReplaceFunctionCall() -> CreateTempFile ->
WriteReplacementInTempFile -> DeleteOriginal -> RenameTempFile ->
DeleteTempFile -> setFilePrivileges

NSIS Script:

...
; Original File for String Replace.

File "/oname=$INSTDIR\filename.txt" ".\filename.txt"

; Starting String Replacment.

!insertmacro AdvReplaceInFile "$INSTDIR\filename.txt" "abc" "xyz" all all


; User is existing in Windows XP Environment.
; This should now change my file privileges on my file which
; should be the file in which the strings are replaced,
; But it is not.

AccessControl::GrantOnFile "$INSTDIR\filename.txt" "Apache" "FullAccess"
AccessControl::SetFileOwner "$INSTDIR\filename.txt" "Apache"
AccessControl::SetFileGroup "$INSTDIR\filename.txt" "ApacheGroup"
...

This seems to be a bug for me.
Is there any workaround instead of truncate my original file and copy content of temp file ?!

Greetings,

Wolfgang.
kichik#
I haven't looked into AdvReplaceInFile, but your flow diagram describes what most of those functions do, so it's probably right. As I said, you have two options. The first, and simpler, is changing that function so it'd create the temporary file in $INSTDIR and not $TEMP. This way, it'll get the attributes of $INSTDIR automatically. Your second option is not to rename at all and manually copy the contents of the file.

However, if all that is wrong is the file owner, you might have a problem with that AccessControl call and all you need to do is fix it. Make sure that call works on the file itself, without calling AdvReplaceInFile.
wilson0x4d#
I've modified AdvReplaceInFile to perform replacements side-by-side with the original file, instead of using %TEMP% (where the inherited permissions restrict the resulting file to the calling user.) I've verified this has the intended effect. The temporary file has the extension ".temp", so if this is an extension you are using for any other purpose you may need to customize futher.


Function AdvReplaceInFile
# adapted from http://nsis.sourceforge.net/More_advanced_replace_text_in_file
Exch $0 ;file to replace in
Exch
Exch $1 ;number to replace after
Exch
Exch 2
Exch $2 ;replace and onwards
Exch 2
Exch 3
Exch $3 ;replace with
Exch 3
Exch 4
Exch $4 ;to replace
Exch 4
Push $5 ;minus count
Push $6 ;universal
Push $7 ;end string
Push $8 ;left string
Push $9 ;right string
Push $R0 ;file1
Push $R1 ;file2
Push $R2 ;read
Push $R3 ;universal
Push $R4 ;count (onwards)
Push $R5 ;count (after)
Push $R6 ;temp file name

StrCpy $R6 "$R0.temp"
FileOpen $R1 $0 r ;file to search in
FileOpen $R0 $R6 w ;temp file
StrLen $R3 $4
StrCpy $R4 -1
StrCpy $R5 -1

loop_read:
ClearErrors
FileRead $R1 $R2 ;read line
IfErrors exit

StrCpy $5 0
StrCpy $7 $R2

loop_filter:
IntOp $5 $5 - 1
StrCpy $6 $7 $R3 $5 ;search
StrCmp $6 "" file_write1
StrCmp $6 $4 0 loop_filter

StrCpy $8 $7 $5 ;left part
IntOp $6 $5 + $R3
IntCmp $6 0 is0 not0
is0:
StrCpy $9 ""
Goto done
not0:
StrCpy $9 $7 "" $6 ;right part
done:
StrCpy $7 $8$3$9 ;re-join

IntOp $R4 $R4 + 1
StrCmp $2 all loop_filter
StrCmp $R4 $2 0 file_write2
IntOp $R4 $R4 - 1

IntOp $R5 $R5 + 1
StrCmp $1 all loop_filter
StrCmp $R5 $1 0 file_write1
IntOp $R5 $R5 - 1
Goto file_write2

file_write1:
FileWrite $R0 $7 ;write modified line
Goto loop_read

file_write2:
FileWrite $R0 $R2 ;write unmodified line
Goto loop_read

exit:
FileClose $R0
FileClose $R1

SetDetailsPrint none
Delete $0
Rename $R6 $0
Delete $R6
SetDetailsPrint both

Pop $R6
Pop $R5
Pop $R4
Pop $R3
Pop $R2
Pop $R1
Pop $R0
Pop $9
Pop $8
Pop $7
Pop $6
Pop $5
Pop $0
Pop $1
Pop $2
Pop $3
Pop $4
FunctionEnd