Go Back   Winamp Forums > Developer Center > NSIS Discussion

Reply
Thread Tools Search this Thread Display Modes
Old 21st October 2011, 03:33   #1
SJSJ
Junior Member
 
Join Date: May 2011
Posts: 25
NSIS FileOpen in read mode is shared?

Hello,

When I open a file in mode "r" - FileOpen "filename" r, does it lock the file for exclusive use? I believe, in "r" mode, the process shouldn't lock the resource.

I have a common file which is written by a java program and read by NSIS. When NSIS opens the file in "r" mode and reads it, the java program throws an exception during its write with the message that the file is in use by another program.

Is there a way in NSIS to open shared resource for reading without locking it?

Thank you!
SJSJ is offline   Reply With Quote
Old 21st October 2011, 13:04   #2
LoRd_MuldeR
Major Dude
 
LoRd_MuldeR's Avatar
 
Join Date: Sep 2005
Location: Somewhere over the Slaughterhouse
Posts: 644
When a file is open for reading, it usually is shared for reading (i.e. no exclusive lock), but not for writing.

And it seems that is what NSIS does:
PHP Code:
HANDLE NSISCALL myOpenFile(const char *fnDWORD daDWORD cd)
{
  
int attr GetFileAttributes(fn);
  return 
CreateFile(
    
fn,
    
da,
    
FILE_SHARE_READ,
    
NULL,
    
cd,
    
attr == INVALID_FILE_ATTRIBUTES attr,
    
NULL
  
);

Sharing a file for writing, while you still are reading from it, is inherently dangerous...

(And, as FILE_SHARE_READ is hardcoded, you cannot change it without re-compiling the EXE headers)

My Plugins: StdUtils | NSISList | CPUFeatures | ExecTimeout | KillProc
My source of inspiration: http://youtu.be/lCwY4_0W1YI
LoRd_MuldeR is offline   Reply With Quote
Old 21st October 2011, 13:12   #3
Lloigor
Junior Member
 
Join Date: Oct 2011
Posts: 9
Just made that, hope that can help..

PHP Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 
Easily opens files with more options than FileOpen
;;   P1 :oHandle returned
;;   P2 :iFile name
;;   P3 :iAccess Mode
;;         'r'  Readonly
;;         'w'  Writeonly
;;         'rw' Read+Write
;;   P4 :iShare mode
;;         ''    None
;;         'r'   Readonly
;;         'rw'  Read+Write
;;         'rwd' Read+Write+Delete
;;   P5 :iCreate mode
;;         ''  Open existing only
;;         'c' Create if not exist
;;         'o' Create and Overwrite
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
!
define FileOpenEx "!insertmacro _FileOpenEx"
!macro _FileOpenEx _Handle_ _File_ _Access_ _Share_ _Create_
   Push 
"${_Create_}"
   
Push "${_Share_}"
   
Push "${_Access_}"
   
Push "${_File_}"
   
Call FileOpenEx
   Pop 
${_Handle_}
!
macroend

Function FileOpenEx  ;; $0:File, $1:Access, $2:Sharing, $3:Create
   Exch 
$0
   Exch
   Exch 
$1
   Exch 2
   Exch 
$2
   Exch 3
   Exch 
$3

   StrCmp 
"r" $1 0 +3
      StrCpy 
$1 0x80000000  ;; GENERIC_READ
      Goto 
+6
   StrCmp 
"w" $1 0 +3
      StrCpy 
$1 0x40000000  ;; GENERIC_WRITE
      Goto 
+3
   StrCmp 
"rw" $1 0 +3
      StrCpy 
$1 0xC0000000  ;; GENERIC_READ GENERIC_WRITE

   StrCmp 
"" $2 0 +3
      StrCpy 
$2 0   ;; FILE_SHARE_NONE
      Goto 
+9
   StrCmp 
"r" $2 0 +3
      StrCpy 
$2 1   ;; FILE_SHARE_READ
      Goto 
+6
   StrCmp 
"rw" $2 0 +3
      StrCpy 
$2 3   ;; FILE_SHARE_READ FILE_SHARE_WRITE
      Goto 
+3
   StrCmp 
"rwd" $2 0 +3
      StrCpy 
$2 7   ;; FILE_SHARE_READ FILE_SHARE_WRITE FILE_SHARE_DELETE

   StrCmp 
"" $3 0 +3
      StrCpy 
$3 3   ;; OPEN_EXISTING
      Goto 
+6
   StrCmp 
"c" $3 0 +3
      StrCpy 
$3 4   ;; OPEN_ALWAYS
      Goto 
+3
   StrCmp 
"o" $3 0 +3
      StrCpy 
$3 2   ;; CREATE_ALWAYS

   System
::Call 'Kernel32::CreateFile(t, i, i, i, i, i, i) i (r0, r1, r2, 0, r3, 0x80, 0) .r2'  ;; Open/Create file

   Pop 
$3
   Pop 
$0
   Pop 
$1
   Exch 
$2
FunctionEnd 
Example:
${FileOpenEx} $0 "SomeFile.ext" "r" "rwd" "" ;; opens SomeFile.ext in read mode with full share access, if it exists

*
Lloigor is offline   Reply With Quote
Old 24th October 2011, 15:09   #4
Afrow UK
Moderator
 
Afrow UK's Avatar
 
Join Date: Nov 2002
Location: Birmingham, England
Posts: 8,202
It might be worth changing all those run time string comparisons to compile time (by using !if).

Stu

Need an installer? http://www.afrowsoft.co.uk
Afrow UK is offline   Reply With Quote
Old 31st October 2011, 05:25   #5
SJSJ
Junior Member
 
Join Date: May 2011
Posts: 25
Thank you, all
SJSJ is offline   Reply With Quote
Old 31st October 2011, 12:16   #6
Lloigor
Junior Member
 
Join Date: Oct 2011
Posts: 9
If you really nead maximum speed, ex: if you open a large amount of files in a tight loop, you may want a more direct approach, something like:
PHP Code:
!define ApiCreateFile "!insertmacro _ApiCreateFile"
!macro _ApiCreateFile _Handle_ _File_ _Access_ _Share_ _Create_
   System
::Call 'Kernel32::CreateFile(t, i, i, i, i, i, i) i ("${_File_}", ${_Access_}, ${_Share_}, 0, ${_Create_}, 0x80, 0) .s'  ;; Open/Create file
   Pop 
${_Handle_}
!
macroend 

Last edited by Lloigor; 31st October 2011 at 13:19.
Lloigor is offline   Reply With Quote
Reply
Go Back   Winamp Forums > Developer Center > NSIS Discussion

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump