Topic 3.4

File System

Working with Files and Directories

In this topic we'll discuss how to work with files and folders. If you run into a situation where the Launcher.ini cannot handle your desired action with [FilesMove] or [DirectoriesMove] (read this for working with the Launcher.ini and the filesystem) than we can use the custom.nsh file to do the required action. I'll be going over and covering the basics from moving files, copying files, deleting files, and so on and so forth.

Redirection

In the last topic we had talked about Registry Redirection, well the same applies to the file system. The %windir%\System32 directory is reserved for 64-bit applications. Most DLL file names were not changed when 64-bit versions of the DLLs were created, so 32-bit versions of the DLLs are stored in a different directory. WOW64 hides this difference by using a file system redirector.

Whenever a 32-bit application attempts to access %windir%\System32, the access is redirected to %windir%\SysWOW64. So with that being said if you tried to access %windir%\regedit.exe with a 32-bit process (which your Launcher.exe will inevitably be) than you are going to be redirected to using %windir%\SysWOW64\regedit.exe. Moreover, the file-system redirector ensures that 32-bit applications which try to access the Program Files folder are redirected to Program Files (x86) instead.

Certain subdirectories are exempt from redirection. Access to these subdirectories is not redirected to %windir%\SysWOW64. The following are the directories which are not affected by the file system redirector:
  • %windir%\system32\catroot
  • %windir%\system32\catroot2
  • %windir%\system32\driverstore
  • %windir%\system32\drivers\etc
  • %windir%\system32\logfiles
  • %windir%\system32\spool

So when writing custom code in our custom.nsh we would use the system plugin with the following call System::Call "kernel32::Wow64EnableWow64FsRedirection(i0)" to disable the file system redirector and use System::Call "kernel32::Wow64EnableWow64FsRedirection(i1)" to enable it. The following code snippet will shed some light on how to use this in action.

;=#
;= DEFINES
!define DISABLEREDIR `kernel32::Wow64EnableWow64FsRedirection(i0)`
!define ENABLEREDIR  `kernel32::Wow64EnableWow64FsRedirection(i1)`

;=#
;= USAGE
IntCmp $Bit 64 0 +5 +5
System::Call `${DISABLEREDIR}`
Rename "$SYSDIR\DRIVERS\driver.sys" "$SYSDIR\DRIVERS\driver.sys.bak"
CopyFiles /SILENT "${DATA}\driver.sys" "$SYSDIR\DRIVERS"
System::Call `${ENABLEREDIR}`
Rename "$SYSDIR\DRIVERS\driver.sys" "$SYSDIR\DRIVERS\driver.sys.bak"
CopyFiles /SILENT "${DATA}\driver.sys" "$SYSDIR\DRIVERS"
Native System Directory
The following only applies to Windows Vista and later but 32-bit applications can access the native system directory by substituting %windir%\Sysnative for %windir%\System32. WOW64 recognizes Sysnative as a special alias used to indicate that the file system should not redirect the access. This mechanism is flexible and easy to use, therefore, it is the recommended mechanism to bypass file system redirection. Note that 64-bit applications cannot use the Sysnative alias as it is a virtual directory not a real one.
User Folders

For user shell folder redirection (C:\Users\USERNAME\Desktop vs. C:\Users\Public\Desktop) we would use SetShellVarContext. There are two parameters available to SetShellVarContext which are current and all. If set to current (default), the current user's shell folders will be used and if set to all, then the Public Folders or All Users shell folders will be used. If a folder isn't found when using the all parameter, then the current user folder will be used.

Please take into consideration that you will have no rights to write in the all users area. Only when you've got administrative privileges will you then have full access rights to the all users area.

;=#
;= USAGE
; SetShellVarContext current|all
;=
; Below will set $0 to contain "C:\Users\demondevin\Desktop" 
; and set $1 to contain "C:\Users\Public\Desktop"
SetShellVarContext current
StrCpy $0 $DESKTOP
SetShellVarContext all
StrCpy $1 $DESKTOP
MessageBox MB_OK $0$\n$1
This page is unfinished and is still being written.
More to come soon.