Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Sebastian Mayr
wine
Commits
814a3fa2
Commit
814a3fa2
authored
23 years ago
by
skeetor
Committed by
Alexandre Julliard
23 years ago
Browse files
Options
Downloads
Patches
Plain Diff
MoveFileEx now enters the files in the registry when the boot delay
flag is set.
parent
f11de4fc
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
files/file.c
+136
-13
136 additions, 13 deletions
files/file.c
with
136 additions
and
13 deletions
files/file.c
+
136
−
13
View file @
814a3fa2
...
...
@@ -2117,6 +2117,99 @@ inline static BOOL is_executable( const char *name )
}
/***********************************************************************
* FILE_AddBootRenameEntry
*
* Adds an entry to the registry that is loaded when windows boots and
* checks if there are some files to be removed or renamed/moved.
* <fn1> has to be valid and <fn2> may be NULL. If both pointers are
* non-NULL then the file is moved, otherwise it is deleted. The
* entry of the registrykey is always appended with two zero
* terminated strings. If <fn2> is NULL then the second entry is
* simply a single 0-byte. Otherwise the second filename goes
* there. The entries are prepended with \??\ before the path and the
* second filename gets also a '!' as the first character if
* MOVEFILE_REPLACE_EXISTING is set. After the final string another
* 0-byte follows to indicate the end of the strings.
* i.e.:
* \??\D:\test\file1[0]
* !\??\D:\test\file1_renamed[0]
* \??\D:\Test|delete[0]
* [0] <- file is to be deleted, second string empty
* \??\D:\test\file2[0]
* !\??\D:\test\file2_renamed[0]
* [0] <- indicates end of strings
*
* or:
* \??\D:\test\file1[0]
* !\??\D:\test\file1_renamed[0]
* \??\D:\Test|delete[0]
* [0] <- file is to be deleted, second string empty
* [0] <- indicates end of strings
*
*/
static
BOOL
FILE_AddBootRenameEntry
(
const
char
*
fn1
,
const
char
*
fn2
,
DWORD
flags
)
{
static
const
char
PreString
[]
=
"
\\
??
\\
"
;
static
const
char
ValueName
[]
=
"PendingFileRenameOperations"
;
BOOL
rc
=
FALSE
;
HKEY
Reboot
=
0
;
DWORD
Type
,
len1
,
len2
,
l
;
DWORD
DataSize
=
0
;
BYTE
*
Buffer
=
NULL
;
if
(
RegCreateKeyA
(
HKEY_LOCAL_MACHINE
,
"SYSTEM
\\
CurrentControlSet
\\
Control
\\
Session Manager"
,
&
Reboot
)
!=
ERROR_SUCCESS
)
{
WARN
(
"Error creating key for reboot managment [%s]
\n
"
,
"SYSTEM
\\
CurrentControlSet
\\
Control
\\
Session Manager"
);
return
FALSE
;
}
l
=
strlen
(
PreString
);
len1
=
strlen
(
fn1
)
+
l
+
1
;
if
(
fn2
)
{
len2
=
strlen
(
fn2
)
+
l
+
1
;
if
(
flags
&
MOVEFILE_REPLACE_EXISTING
)
len2
++
;
/* Plus 1 because of the leading '!' */
}
else
len2
=
1
;
/* minimum is the 0 byte for the empty second string */
/* First we check if the key exists and if so how many bytes it already contains. */
if
(
RegQueryValueExA
(
Reboot
,
ValueName
,
NULL
,
&
Type
,
NULL
,
&
DataSize
)
==
ERROR_SUCCESS
)
{
if
(
Type
!=
REG_MULTI_SZ
)
goto
Quit
;
if
(
!
(
Buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
DataSize
+
len1
+
len2
+
1
)))
goto
Quit
;
if
(
RegQueryValueExA
(
Reboot
,
ValueName
,
NULL
,
&
Type
,
Buffer
,
&
DataSize
)
!=
ERROR_SUCCESS
)
goto
Quit
;
if
(
DataSize
)
DataSize
--
;
/* remove terminating null (will be added back later) */
}
else
{
if
(
!
(
Buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len1
+
len2
+
1
)))
goto
Quit
;
DataSize
=
0
;
}
sprintf
(
Buffer
+
DataSize
,
"%s%s"
,
PreString
,
fn1
);
DataSize
+=
len1
;
if
(
fn2
)
{
sprintf
(
Buffer
+
DataSize
,
"%s%s%s"
,
(
flags
&
MOVEFILE_REPLACE_EXISTING
)
?
"!"
:
""
,
PreString
,
fn2
);
DataSize
+=
len2
;
}
else
Buffer
[
DataSize
++
]
=
0
;
Buffer
[
DataSize
++
]
=
0
;
/* add final null */
rc
=
!
RegSetValueExA
(
Reboot
,
ValueName
,
0
,
REG_MULTI_SZ
,
Buffer
,
DataSize
);
Quit:
if
(
Reboot
)
RegCloseKey
(
Reboot
);
if
(
Buffer
)
HeapFree
(
GetProcessHeap
(),
0
,
Buffer
);
return
(
rc
);
}
/**************************************************************************
* MoveFileExA (KERNEL32.@)
*/
...
...
@@ -2126,26 +2219,57 @@ BOOL WINAPI MoveFileExA( LPCSTR fn1, LPCSTR fn2, DWORD flag )
TRACE
(
"(%s,%s,%04lx)
\n
"
,
fn1
,
fn2
,
flag
);
/* FIXME: <Gerhard W. Gruber>sparhawk@gmx.at
In case of W9x and lesser this function should return 120 (ERROR_CALL_NOT_IMPLEMENTED)
to be really compatible. Most programs wont have any problems though. In case
you encounter one, this is what you should return here. I don't know what's up
with NT 3.5. Is this function available there or not?
Does anybody really care about 3.5? :)
*/
/* Filename1 has to be always set to a valid path. Filename2 may be NULL
if the source file has to be deleted.
*/
if
(
!
fn1
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
FALSE
;
}
if
(
!
DOSFS_GetFullName
(
fn1
,
TRUE
,
&
full_name1
))
return
FALSE
;
/* This function has to be run through in order to process the name properly.
If the BOOTDELAY flag is set, the file doesn't need to exist though. At least
that is the behaviour on NT 4.0. The operation accepts the filenames as
they are given but it can't reply with a reasonable returncode. Success
means in that case success for entering the values into the registry.
*/
if
(
!
DOSFS_GetFullName
(
fn1
,
TRUE
,
&
full_name1
))
{
if
(
!
(
flag
&
MOVEFILE_DELAY_UNTIL_REBOOT
))
return
FALSE
;
}
if
(
fn2
)
/* !fn2 means delete fn1 */
{
if
(
DOSFS_GetFullName
(
fn2
,
TRUE
,
&
full_name2
))
if
(
DOSFS_GetFullName
(
fn2
,
TRUE
,
&
full_name2
))
{
/* target exists, check if we may overwrite */
if
(
!
(
flag
&
MOVEFILE_REPLACE_EXISTING
))
if
(
!
(
flag
&
MOVEFILE_DELAY_UNTIL_REBOOT
))
{
/* FIXME: Use right error code */
SetLastError
(
ERROR_ACCESS_DENIED
);
return
FALSE
;
/* target exists, check if we may overwrite */
if
(
!
(
flag
&
MOVEFILE_REPLACE_EXISTING
))
{
/* FIXME: Use right error code */
SetLastError
(
ERROR_ACCESS_DENIED
);
return
FALSE
;
}
}
}
else
{
if
(
!
DOSFS_GetFullName
(
fn2
,
FALSE
,
&
full_name2
))
{
if
(
!
(
flag
&
MOVEFILE_DELAY_UNTIL_REBOOT
))
return
FALSE
;
}
}
else
if
(
!
DOSFS_GetFullName
(
fn2
,
FALSE
,
&
full_name2
))
return
FALSE
;
/* Source name and target path are valid */
...
...
@@ -2156,8 +2280,8 @@ BOOL WINAPI MoveFileExA( LPCSTR fn1, LPCSTR fn2, DWORD flag )
when exiting... What about using on_exit(2)
*/
FIXME
(
"Please move existing file '%s' to file '%s' when Wine has finished
\n
"
,
f
ull_name1
.
long_name
,
full_name2
.
long_name
);
return
TRUE
;
f
n1
,
fn2
);
return
FILE_AddBootRenameEntry
(
fn1
,
fn2
,
flag
)
;
}
if
(
full_name1
.
drive
!=
full_name2
.
drive
)
...
...
@@ -2204,9 +2328,8 @@ BOOL WINAPI MoveFileExA( LPCSTR fn1, LPCSTR fn2, DWORD flag )
Perhaps we should queue these command and execute it
when exiting... What about using on_exit(2)
*/
FIXME
(
"Please delete file '%s' when Wine has finished
\n
"
,
full_name1
.
long_name
);
return
TRUE
;
FIXME
(
"Please delete file '%s' when Wine has finished
\n
"
,
fn1
);
return
FILE_AddBootRenameEntry
(
fn1
,
NULL
,
flag
);
}
if
(
unlink
(
full_name1
.
long_name
)
==
-
1
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment